<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      // 重写call 方法
      Function.prototype.call = function (thisObj, ...arge) {
        // 判断传入的obj是否是undefined或null  如果是则将对象指向指向window
        if (thisObj === undefined || thisObj === null) {
          thisObj = Window;
        }

        // this 指向调用call方法的函数

        // 将传入的对象添加一个临时的方法，调用此方法this则指向这个对象
        thisObj.tempFn = this;
        // 调用这个方法
        let result = thisObj.tempFn(...arge);
        // 删除临时方法
        delete thisObj.tempFn;
        // 返回结果
        return result;
      };

      function a(b, c) {
        console.log(this, b, c);
      }

      let obj = { a: 1 };

      a.call(obj, 1, 2);

      //   重写apply方法
      Function.prototype.apply = function (thisObj, arge) {
        return this.call(thisObj, ...arge);
      };

      a.apply(obj, [1, 2]);

      //重写bind方法
      Function.prototype.bind = function (thisObj, ...arge) {
        return (...arge2) => {
          return this.call(thisObj, ...arge, ...arge2);
        };
      };

      let fn1 = a.bind(obj, 1);
      fn1(2, 3);
    </script>
  </body>
</html>
